using B.Z.BasicData.Infrastructure;
using B.Z.Inventory.API.Read.Application.Command;
using B.Z.Inventory.API.Read.DTO;
using B.Z.Inventory.Domain;
using MediatR;
using Microsoft.AspNetCore.SignalR;

namespace B.Z.Inventory.API.Read.Services
{
    /// <summary>
    /// 库存监控后台服务
    /// </summary>
    public class InventoryMonitoringService : BackgroundService
    {
        private readonly IServiceProvider serviceProvider;
        private readonly ILogger<InventoryMonitoringService> logger;
        private readonly TimeSpan checkInterval = TimeSpan.FromMinutes(5); // 每5分钟检查一次

        public InventoryMonitoringService(IServiceProvider serviceProvider, ILogger<InventoryMonitoringService> logger)
        {
            this.serviceProvider = serviceProvider;
            this.logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            logger.LogInformation("库存监控服务已启动");

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    await CheckInventoryAlerts();
                    await Task.Delay(checkInterval, stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    // 正常取消，退出循环
                    break;
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "库存监控服务执行时发生错误");
                    // 发生错误时等待更长时间再重试
                    await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                }
            }

            logger.LogInformation("库存监控服务已停止");
        }

        private async Task CheckInventoryAlerts()
        {
            using var scope = serviceProvider.CreateScope();
            var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
            var hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<InventoryReadHub>>();

            try
            {
                // 执行库存预警检查
                var alertCommand = new LowStockAlertCommand();
                var alertResult = await mediator.Send(alertCommand);

                if (alertResult.Code == B.Z.Inventory.ErrorCode.APIEnums.ok && 
                    alertResult.Data != null && 
                    alertResult.Data.TotalAlertCount > 0)
                {
                    // 推送预警信息到所有连接的客户端
                    await hubContext.Clients.All.SendAsync("ReceiveLowStockAlert", alertResult.Data);

                    // 发送系统消息
                    var systemMessage = new SystemMessageDto
                    {
                        MessageId = Guid.NewGuid().ToString(),
                        MessageType = "LowStockAlert",
                        Title = "库存预警",
                        Content = $"检测到 {alertResult.Data.TotalAlertCount} 个商品库存不足，请及时补货",
                        MessageTime = DateTime.Now,
                        Level = "warning"
                    };

                    await hubContext.Clients.All.SendAsync("ReceiveSystemMessage", systemMessage);

                    logger.LogWarning($"检测到库存预警：{alertResult.Data.TotalAlertCount} 个商品库存不足");

                    // 如果有紧急缺货情况，发送高优先级通知
                    var urgentItems = alertResult.Data.LowStockItems.Where(x => x.AlertLevel == 3).ToList();
                    if (urgentItems.Any())
                    {
                        var urgentMessage = new SystemMessageDto
                        {
                            MessageId = Guid.NewGuid().ToString(),
                            MessageType = "UrgentStockAlert",
                            Title = "紧急库存警告",
                            Content = $"以下商品已断货：{string.Join(", ", urgentItems.Select(x => x.GoodsName))}",
                            MessageTime = DateTime.Now,
                            Level = "error"
                        };

                        await hubContext.Clients.All.SendAsync("ReceiveSystemMessage", urgentMessage);
                        logger.LogError($"紧急库存警告：{urgentItems.Count} 个商品已断货");
                    }
                }
                else
                {
                    logger.LogInformation("库存状态正常，无预警项目");
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "执行库存预警检查时发生错误");
            }
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            logger.LogInformation("正在停止库存监控服务...");
            await base.StopAsync(cancellationToken);
        }
    }
}